﻿using System;
using System.Collections.Generic;
using GrainManage.Entities.Image;
using GrainManage.Server.Factory;
using System.Web;
using System.IO;
using GrainManage.Data.Util;

namespace GrainManage.Server.Business
{
    class ImageBusiness : BaseBusiness, GrainManage.Interface.IImage
    {

        //************************************************POST************************************************

        public OutputGetImages GetImages(InputGetImages input)
        {
            var result = new OutputGetImages();
            try
            {
                var service = ObjectFactory.GetImageService(input);
                result.Images = service.GetImages(input.WithFile, input, result);
                if (input.DesiredSize != null && input.DesiredSize.Width > 0 && input.DesiredSize.Height > 0)
                {
                    foreach (var image in result.Images)
                    {
                        image.File = GetThumb(input.DesiredSize.Width, input.DesiredSize.Height, Path.GetExtension(image.ImageName), image.File);
                    }
                }

                if (result.Images.Count == 0)
                {
                    SetResponse(StatusCode.NoData, result);
                }
                else
                {
                    SetResponse(StatusCode.Success, result);
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, result, e.Message);
                WriteLog(System.Reflection.MethodBase.GetCurrentMethod(), e, input, result);
            }

            return result;
        }

        public OutputGetImageFile GetImageFile(InputGetImageFile input)
        {
            var result = new OutputGetImageFile();
            try
            {
                var userName = input.Authentication != null ? input.Authentication.UserName : null;
                var absolutePath = GetAbsolutePath(input.ImageName, input.Authentication.UserName);
                var data = ReadFile(absolutePath);
                if (input.DesiredSize != null && input.DesiredSize.Width > 0 && input.DesiredSize.Height > 0)
                {
                    data = GetThumb(input.DesiredSize.Width, input.DesiredSize.Height, input.ImageName, data);
                }
                if (data != null)
                {
                    SetResponse(StatusCode.Success, result);
                }
                else
                {
                    SetResponse(StatusCode.FileNotExist, result);
                }
            }
            catch (System.IO.IOException e)
            {
                SetResponse(StatusCode.IOError, result);
                WriteLog(System.Reflection.MethodBase.GetCurrentMethod(), e, input, result);
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, result, e.Message);
                WriteLog(System.Reflection.MethodBase.GetCurrentMethod(), e, input, result);
            }

            return result;
        }

        public OutputGetImageUrl GetImageUrl(InputGetImageUrl input)
        {
            var result = new OutputGetImageUrl();
            try
            {
                if (IsFileExists(GetAbsolutePath(input.ImageName, input.Authentication.UserName)))
                {
                    var service = ObjectFactory.GetImageService(null);
                    var imageID = service.GetImageID(input.ImageName, input.Authentication.UserName);
                    result.ImageUrl = service.GetImageUrl(imageID);
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, result, e.Message);
                WriteLog(System.Reflection.MethodBase.GetCurrentMethod(), e, input, result);
            }
            return result;
        }

        public OutputInsert Insert(InputInsert input)
        {
            var result = new OutputInsert();
            try
            {
                var service = ObjectFactory.GetImageService(input);
                if (service.GetImageID(input.Image.ImageName, input.Authentication.UserName) > 0)
                {
                    SetResponse(StatusCode.FileHasExist, result);
                }
                else
                {
                    var absolutePath = GetAbsolutePath(input.Image.ImageName, input.Authentication.UserName);
                    SaveFile(absolutePath, input.Image.File);
                    result.ImageID = service.Insert(input.Image);
                    if (result.ImageID > 0)
                    {
                        SetResponse(StatusCode.Success, result);
                    }
                    else
                    {
                        DeleteFile(absolutePath);
                        SetResponse(StatusCode.InsertFailed, result);
                    }
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, result, e.Message);
                WriteLog(System.Reflection.MethodBase.GetCurrentMethod(), e, input, result);
            }

            return result;
        }

        public OutputUpdate Update(InputUpdate input)
        {
            var result = new OutputUpdate();
            try
            {
                var service = ObjectFactory.GetImageService(input);
                if (service.Update(input.Image) > 0)
                {
                    if (input.Image.File != null)
                    {
                        var absolutePath = GetAbsolutePath(input.Image.ImageName, input.Authentication.UserName);
                        DeleteFile(absolutePath);
                        SaveFile(absolutePath, input.Image.File);
                    }
                    SetResponse(StatusCode.Success, result);
                }
                else
                {
                    SetResponse(StatusCode.UpdateFailed, result);
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, result, e.Message);
                WriteLog(System.Reflection.MethodBase.GetCurrentMethod(), e, input, result);
            }
            return result;
        }

        public OutputDelete Delete(InputDelete input)
        {
            var result = new OutputDelete();
            try
            {
                var service = ObjectFactory.GetImageService(input);
                var path = service.GetImagePath(input.ImageID);
                if (service.Delete(input.ImageID) > 0)
                {
                    if (IsFileExists(path))
                    {
                        System.IO.File.Delete(path);
                    }
                    SetResponse(StatusCode.Success, result);
                }
                else
                {
                    SetResponse(StatusCode.DeleteFailed, result);
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, result, e.Message);
                WriteLog(System.Reflection.MethodBase.GetCurrentMethod(), e, input, result);
            }

            return result;
        }

        #region 辅助方法

        //生成缩略图
        private byte[] GetThumb(int width, int height, string imageName, byte[] data)
        {
            var thumbData = data;
            if (data != null)
            {
                thumbData = GrainManage.Server.Tool.Thumbnail.ZoomThumbnail(Path.GetExtension(imageName), data, width, height);
            }
            return thumbData;
        }

        private string GetAbsolutePath(string imageName, string userName)
        {
            var absolutePath = string.Empty;
            var service = ObjectFactory.GetImageService(null);
            var imageID = service.GetImageID(imageName, userName);
            absolutePath = service.GetImagePath(imageID);
            return absolutePath;
        }

        private bool SaveFile(string absolutePath, byte[] photo)
        {
            bool isSuccess = false;
            if (photo != null && !IsFileExists(absolutePath))
            {
                System.IO.File.WriteAllBytes(absolutePath, photo);
                isSuccess = true;
            }
            return isSuccess;
        }

        private byte[] ReadFile(string absolutePath)
        {
            byte[] file = null;
            if (IsFileExists(absolutePath))
            {
                file = System.IO.File.ReadAllBytes(absolutePath);
            }
            return file;
        }

        private bool DeleteFile(string absolutePath)
        {
            bool isSuccess = false;
            if (IsFileExists(absolutePath))
            {
                System.IO.File.Delete(absolutePath);
                isSuccess = true;
            }
            return isSuccess;
        }

        private bool IsFileExists(string absolutePath)
        {
            return System.IO.File.Exists(absolutePath);
        }

        #endregion

    }
}
